package org.zjh.controller;

import org.zjh.constant.GameConstant;
import org.zjh.controller.listener.UpdatePlayerOkLis;
import org.zjh.controller.timer.CallPointTimer;
import org.zjh.controller.timer.DealPokersTimer;
import org.zjh.controller.timer.DiscardPokersTimer;
import org.zjh.model.ComputerPlayer;
import org.zjh.model.Player;
import org.zjh.model.Poker;
import org.zjh.model.RealPlayer;
import org.zjh.utils.AccountUtil;
import org.zjh.utils.MySQLUtil;
import org.zjh.utils.VerificationUtil;
import org.zjh.view.game.GameMenuFrame;
import org.zjh.view.ui.GameUi;

import javax.swing.*;
import java.util.ArrayList;

/**
 * 游戏控制器类
 */

public class GameController {
    //真实玩家
    private RealPlayer player;
    //电脑玩家A
    private ComputerPlayer computerA;
    //电脑玩家B
    private ComputerPlayer computerB;
    //当前玩家
    private Player currentPlayer;
    //当前叫分玩家
    private Player callPointCurrentPlayer;
    //地主玩家
    private Player landOwnerPlayer;
    //当前出牌玩家
    private Player curDiscardPokerPlayer;
    //发牌索引
    private int currentPokerIndex = 0;
    //扑克牌集合
    private ArrayList<Poker> pokerBoxList = new ArrayList<>();
    //地主牌集合
    private ArrayList<Poker> landOwnerPokerList = new ArrayList<>();
    //当前牌桌上的牌
    private ArrayList<Poker> nowDeskPokerList = new ArrayList<>();

    //发牌定时器
    private DealPokersTimer dealCardsTimer;
    //叫分定时器
    private CallPointTimer callPointTimer;
    //出牌定时器
    private DiscardPokersTimer discardPokersTimer;
    private static GameController gameController = new GameController();



    private GameController() {
        player = new RealPlayer();
    }

    public void start() {
        new GameUi();
        dealCardsTimer = new DealPokersTimer();
        callPointTimer = new CallPointTimer();
        discardPokersTimer = new DiscardPokersTimer();
    }


    /**
     * 登入方法
     */
    public void login() {
        //获取用户输入的账号 密码 验证码
        String inputAccount = GameUi.loginFrame.getLoginPanel().getAccountTextField().getText();
        String inputPassword = GameUi.loginFrame.getLoginPanel().getPasswordField().getText();
        String inputVerificationCode = GameUi.loginFrame.getLoginPanel().getVerificationTextField().getText();
        //判断账号、密码 是否为空
        if (inputAccount.isEmpty() || inputPassword.isEmpty()) {
            //刷新页面
            GameUi.loginFrame.getLoginPanel().refresh();
            //弹出账号密码为空信息
            JOptionPane.showMessageDialog(null, "账号密码不能为空", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;
        }
        //检查验证码是否为空
        if (inputVerificationCode.isEmpty()) {
            //刷新页面
            GameUi.loginFrame.getLoginPanel().refresh();
            //弹出验证码为空
            JOptionPane.showMessageDialog(null, "验证码为空", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;
        }
        //检查验证码是否正确
        if (!VerificationUtil.checkVerificationCode(inputVerificationCode)) {
            //刷新页面
            GameUi.loginFrame.getLoginPanel().refresh();
            //弹出验证码错误信息
            JOptionPane.showMessageDialog(null, "验证码错误", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;
        }
        //查找数据库是否存在用户
        if (!MySQLUtil.getPlayerInfo(inputAccount, inputPassword)) {
            //刷新页面
            GameUi.loginFrame.getLoginPanel().refresh();
            JOptionPane.showMessageDialog(null, "账号密码错误", "温馨提醒", JOptionPane.ERROR_MESSAGE);
        } else {
            //刷新页面
            GameUi.loginFrame.getLoginPanel().refresh();
            //弹出登入成功信息
            JOptionPane.showMessageDialog(null, "登入成功", "温馨提醒", JOptionPane.INFORMATION_MESSAGE);
            //登入页面设置不可见
            GameUi.loginFrame.setVisible(false);
            //将主页面设为不可见
            GameUi.appFrame.setVisible(false);
            //玩家属性赋值
            GameController.getInstance().getPlayer().setAccount(inputAccount);
            //创建游戏菜单窗口
            GameUi.gameMenuFrame = new GameMenuFrame();
        }
    }


    /**
     * 注册方法
     */
    public void register() {
        //获取用户输入的昵称
        String nickname = GameUi.registerFrame.getRegisterPanel().getNicknameTextField().getText();
        //获取用户输入的密码
        String password = GameUi.registerFrame.getRegisterPanel().getPasswordField().getText();
        //获取用户输入的确认密码
        String okPassword = GameUi.registerFrame.getRegisterPanel().getOkPasswordField().getText();
        //生成唯一账号
        String account = AccountUtil.generateRandomAccount();
        //获得用户设置的密保问题一
        String securityIssues1 = GameUi.registerFrame.getRegisterPanel().getSecurityIssuesTextField1().getText();
        //获得密保问题一 的答案
        String securityIssuesAnswer1 = GameUi.registerFrame.getRegisterPanel().getSecurityIssuesAnswerTextField1().getText();
        //获得用户设置的密保问题二
        String securityIssues2 = GameUi.registerFrame.getRegisterPanel().getSecurityIssuesTextField2().getText();
        //获得密保问题二 的答案
        String securityIssuesAnswer2 = GameUi.registerFrame.getRegisterPanel().getSecurityIssuesAnswerTextField2().getText();


        // 检查昵称、密码、密保问题、答案是否为空或空字符串
        if (nickname.isEmpty() || password.isEmpty() || okPassword.isEmpty() || securityIssues1.isEmpty() ||
                securityIssuesAnswer1.isEmpty() || securityIssues2.isEmpty() || securityIssuesAnswer2.isEmpty()) {
            GameUi.registerFrame.getRegisterPanel().refresh();
            JOptionPane.showMessageDialog(null, "上述信息不能为空", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return; // 方法结束 密保为空或者空字符串
        }
        // 检查密码是否一致
        if (!password.equals(okPassword)) {
            GameUi.registerFrame.getRegisterPanel().refresh();
            JOptionPane.showMessageDialog(null, "密码不一致", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return; // 方法结束 密码不一致
        }

        // 检查昵称是否已被占用（注意：这里应该先检查密码再检查昵称，因为密码不一致就应该立即返回）
        if (MySQLUtil.isExist(null, nickname)) {
            GameUi.registerFrame.getRegisterPanel().refresh();
            JOptionPane.showMessageDialog(null, "昵称已被占用了", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return; // 方法结束 昵称已被占用
        }


        // 插入数据库并处理结果
        if (MySQLUtil.insert(nickname, account, password, GameConstant.DEFAULT_SCORE, securityIssues1, securityIssuesAnswer1, securityIssues2, securityIssuesAnswer2)) {
            //刷新页面
            GameUi.registerFrame.getRegisterPanel().refresh();
            //弹出注册成功信息
            JOptionPane.showMessageDialog(null, "注册成功 你的账号是:" + account, "温馨提醒", JOptionPane.INFORMATION_MESSAGE);
            //设置注册窗口不可见
            GameUi.registerFrame.setVisible(false);
        } else {
            //刷新页面
            GameUi.registerFrame.getRegisterPanel().refresh();
            //没注册成功 弹出注册功能异常
            JOptionPane.showMessageDialog(null, "注册功能异常", "温馨提醒", JOptionPane.ERROR_MESSAGE);
        }
    }


    /**
     * 选择找回密码的方式
     */
    public void selectFindPasswordWay() {

        //获取到用户输入的账号、昵称
        String inputAccount = GameUi.findPasswordWayFrame.getFindPasswordWayPanel().getAccountTextField().getText();
        String inputNickname = GameUi.findPasswordWayFrame.getFindPasswordWayPanel().getNicknameTextField().getText();

        if (inputAccount.isEmpty() && inputNickname.isEmpty()) {
            JOptionPane.showMessageDialog(null, "必须选择一种方式输入", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;
        }

        //通过输入的账号或者昵称去数据库中寻找是否有对应的信息
        if (MySQLUtil.isExist(inputAccount, inputNickname)) {

            //把正确的账号或昵称 传到重置密码按钮监听那
            UpdatePlayerOkLis.getInstance().setAccount(inputAccount);
            UpdatePlayerOkLis.getInstance().setNickname(inputNickname);

            //查询到 进入到找回密码界面 显示账户对应的密保问题以及 以及重置密码
            GameUi.findPasswordWayFrame.setVisible(false);
            GameUi.updatePlayerInfoFrame.setVisible(true);

            //调用数据库工具类获得对应的密保问题
            MySQLUtil.getSecurityIssues(inputAccount, inputNickname);
            //刷新找回密码界面
            GameUi.findPasswordWayFrame.getFindPasswordWayPanel().refresh();
        } else { //没有查询到
            //刷新页面
            GameUi.findPasswordWayFrame.getFindPasswordWayPanel().refresh();
            JOptionPane.showMessageDialog(null, "没有该用户信息", "温馨提醒", JOptionPane.ERROR_MESSAGE);
        }
    }


    /**
     * 修改玩家信息
     * @param account 账户
     * @param nickname 昵称
     * @param correctAnswer1 正确答案1
     * @param correctAnswer2 正确答案2
     */
    public void updateUserInfo(String account, String nickname, String correctAnswer1, String correctAnswer2) {

        //获得用户输入的密保问题一的答案
        String answer1 = GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().getAnswerTextField1().getText();
        //获得用户输入的密保问题二的答案
        String answer2 = GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().getAnswerTextField2().getText();
        //获得用户输入的新昵称
        String newNickname = GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().getNewNicknameField().getText();
        //获得用户输入 重置的密码
        String resetPassword = GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().getResetPasswordField().getText();
        //获得用户输入的确认重置的密码
        String okResetPassword = GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().getOkResetPasswordField().getText();

        //判断密保问题一、密保问题二、密码、重置密码是否为空
        if (answer1.isEmpty() || answer2.isEmpty() || resetPassword.isEmpty() || okResetPassword.isEmpty()) {
            //弹出信息 密保答案或密码不能为空
            JOptionPane.showMessageDialog(null, "密保答案或密码不能为空", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return; //方法结束
        }


        //判断密保问题是否正确
        if (!(correctAnswer1.equals(answer1) && correctAnswer2.equals(answer2))) {
            //页面文本框刷新
            GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().refresh();
            //弹出密保问题不正确信息
            JOptionPane.showMessageDialog(null, "密保答案错误", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;//方法结束
        }

        //判断两次密码输入 是否一致
        if (!resetPassword.equals(okResetPassword)) {
            //页面文本框刷新
            GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().refresh();
            //弹出 密码不一致信息
            JOptionPane.showMessageDialog(null, "密码输入不一致", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;
        }

        //判断新昵称是否在数据库中已经存在
        if (MySQLUtil.isExist(null, newNickname)) {
            //页面文本框刷新
            GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().refresh();
            //提示用户 昵称已经被占用了
            JOptionPane.showMessageDialog(null, "昵称已被占用", "温馨提醒", JOptionPane.ERROR_MESSAGE);
            return;//方法结束
        }
        //修改数据库中的密码

        if (MySQLUtil.updatePlayerInfo(nickname, newNickname, account, resetPassword)) {
            JOptionPane.showMessageDialog(null, "修改成功", "温馨提醒", JOptionPane.INFORMATION_MESSAGE);
            //页面文本框刷新
            GameUi.updatePlayerInfoFrame.getUpdatePlayerInfoPanel().refresh();
            //页面设置不可见
            GameUi.updatePlayerInfoFrame.setVisible(false);
        }
    }










    public static GameController getInstance() {
        return gameController;
    }


    public RealPlayer getPlayer() {
        return player;
    }

    public void setPlayer(RealPlayer player) {
        this.player = player;
    }


    public ComputerPlayer getComputerA() {
        return computerA;
    }

    public void setComputerA(ComputerPlayer computerA) {
        this.computerA = computerA;
    }

    public ComputerPlayer getComputerB() {
        return computerB;
    }

    public void setComputerB(ComputerPlayer computerB) {
        this.computerB = computerB;
    }

    public void setCurrentPlayer(Player currentPlayer) {
        this.currentPlayer = currentPlayer;
    }

    public Player getCurrentPlayer() {
        return currentPlayer;
    }

    public int getCurrentPokerIndex() {
        return currentPokerIndex;
    }

    public void setCurrentPokerIndex(int currentPokerIndex) {
        this.currentPokerIndex = currentPokerIndex;
    }

    public ArrayList<Poker> getPokerBoxList() {
        return pokerBoxList;
    }

    public void setPokerBoxList(ArrayList<Poker> pokerBoxList) {
        this.pokerBoxList = pokerBoxList;
    }

    public DealPokersTimer getDealCardsTimer() {
        return dealCardsTimer;
    }

    public ArrayList<Poker> getLandOwnerPokerList() {
        return landOwnerPokerList;
    }

    public void setLandOwnerPokerList(ArrayList<Poker> landOwnerPokerList) {
        this.landOwnerPokerList = landOwnerPokerList;
    }

    public Player getCallPointCurrentPlayer() {
        return callPointCurrentPlayer;
    }

    public void setCallPointCurrentPlayer(Player callPointCurrentPlayer) {
        this.callPointCurrentPlayer = callPointCurrentPlayer;
    }

    public CallPointTimer getCallPointTimer() {
        return callPointTimer;
    }


    public DiscardPokersTimer getDiscardPokersTimer() {
        return discardPokersTimer;
    }



    public Player getCurDiscardPokerPlayer() {
        return curDiscardPokerPlayer;
    }

    public void setCurDiscardPokerPlayer(Player curDiscardPokerPlayer) {
        this.curDiscardPokerPlayer = curDiscardPokerPlayer;
    }

    public ArrayList<Poker> getNowDeskPokerList() {
        return nowDeskPokerList;
    }

    public Player getLandOwnerPlayer() {
        return landOwnerPlayer;
    }

    public void setLandOwnerPlayer(Player landOwnerPlayer) {
        this.landOwnerPlayer = landOwnerPlayer;
    }
}
